package com.mohe.shanpao.shiro;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.mohe.shanpao.domain.user.SysFunction;
import com.mohe.shanpao.service.user.SysFunctionService;
import com.mohe.shanpao.service.user.impl.SysFunctionServiceImpl;
import com.mohe.shanpao.utils.Constants;

/**
 * shiro配置
 * 
 * @author  caixiang
 * @version  [版本号, 2016年6月17日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@Configuration
//@ComponentScan("cn.mohe.shanpao")
public class ShiroConfiguration
{  
    @Autowired
    SysFunctionService sysFunctionService;
    
    @Autowired
    DataSource dataSource;
    
    /**
     * 获取自定义realm
     * @return realm
     */
    @Bean(name = "shiroRealm")
    public ShiroRealm getShiroRealm() {
    	ShiroRealm realm = new ShiroRealm();
    	realm.setCredentialsMatcher(getCredentialsMatcher());
    	
    	realm.setCachingEnabled(true);
    	realm.setAuthenticationCachingEnabled(true);
    	realm.setAuthenticationCacheName("authenticationCache");
    	realm.setAuthorizationCachingEnabled(true);
    	realm.setAuthorizationCacheName("authorizationCache");
    	
        return realm;
    }
    
    @Bean(name = "credentialsMatcher")
    public RetryLimitHashedCredentialsMatcher getCredentialsMatcher() {
    	
    	RetryLimitHashedCredentialsMatcher matcher = new RetryLimitHashedCredentialsMatcher(getEhCacheManager());
    	matcher.setHashIterations(2);
    	matcher.setHashAlgorithmName(Constants.DEAFULT_ALGORITHM_NAME);
    	matcher.setStoredCredentialsHexEncoded(true);
    	
    	return matcher;
    }
    
    @Bean(name = "sysFunctionService")
    public SysFunctionService getSysFunctionService() {
        return new SysFunctionServiceImpl();
    }
    
    /**
     * 自定义security manager
     * @return
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {  
        return new LifecycleBeanPostProcessor();  
    }
    
    @Bean
	public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
		daap.setProxyTargetClass(true);
		return daap;
	}
    
    @Bean(name = "shiroEhcacheManager")
	public EhCacheManager getEhCacheManager() {
		EhCacheManager em = new EhCacheManager();
		em.setCacheManagerConfigFile("classpath:ehcache.xml");
		return em;
	}
    
	@Bean(name = "securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager() {
		DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
		dwsm.setRealm(getShiroRealm());
		dwsm.setCacheManager(getEhCacheManager());
		return dwsm;
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
		AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
		aasa.setSecurityManager(getDefaultWebSecurityManager());
		return new AuthorizationAttributeSourceAdvisor();
	}

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean() {

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());
        //没有权限或者失败后跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        //成功后跳转的页面
        shiroFilterFactoryBean.setSuccessUrl("/index.html");
        //未授权后跳转的页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/404.html");
        
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); 
        //静态资源
        filterChainDefinitionMap.put("/login.html", "anon");
        
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/image/**", "anon");
        filterChainDefinitionMap.put("/images/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        //其他
        filterChainDefinitionMap.put("/anon/**", "anon");
        filterChainDefinitionMap.put("/vendor/**", "anon");
        filterChainDefinitionMap.put("/lib/**", "anon");
        //动作
        filterChainDefinitionMap.put("/doLogin", "anon");
        filterChainDefinitionMap.put("/logout", "anon");
        
        //爬虫
        filterChainDefinitionMap.put("/crawl/**", "anon");
        
        List<SysFunction> sysFunctionList = getSysFunctionService().selectAll();
        for(SysFunction sysFunction : sysFunctionList)
        {
            filterChainDefinitionMap.put(sysFunction.getUrl(), "perms[" + sysFunction.getPermission() + "]");
        }
        
        filterChainDefinitionMap.put("/**", "authc");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
    
}
